package com.gearbox.core.task;

import com.gearbox.core.cache.NodeIdleTimeCache;
import com.gearbox.core.configuration.SystemConfiguration;
import com.gearbox.core.service.NodeService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class NodeStatusUpdateTask {
    private static final Logger LOG = LoggerFactory.getLogger(NodeStatusUpdateTask.class);

    @Autowired
    private NodeService nodeService;

    @Autowired
    private NodeIdleTimeCache nodeIdleTimeCache;

    @Autowired
    private SystemConfiguration systemConfiguration;

    @Scheduled(initialDelay = 10L, fixedDelayString = "${task.scale-in-period}", timeUnit = TimeUnit.SECONDS)
    void setNodesToDrain() {
        try {
            LOG.info("setNodesToDrain begin");
            nodeIdleTimeCache.getAllNodeNames()
                .stream()
                .filter(nodeName -> nodeIdleTimeCache.getAggregateIdleTime(nodeName) > systemConfiguration.getScaleInTime())
                .forEach(this::setDrain);
            LOG.info("setNodesToDrain end");
        } catch (Throwable e) {
            LOG.error("setNodesToDrain error", e);
        }
    }

    void setDrain(String nodeName) {
        try {
            nodeService.setToDrain(nodeName);
        } catch (Exception e) {
            LOG.error("set node[{}] state to Drain failed", nodeName, e);
        }
    }
}
